﻿using System.Collections.Generic;
using System.Collections;

namespace MMessaging.MessagingEx.Common
{
	public class MMessageProcessing<TMESSAGETYPE> 
	{
		private readonly MMessagingHandlerContext<TMESSAGETYPE> _context;
		public string Name { get; private set; }
		public delegate IEnumerable<MMessageProcessing<TMESSAGETYPE>> HandlerFunc(MMessagingHandlerContext<TMESSAGETYPE> context);

		public bool IsFinished { get; private set; }

		private readonly IEnumerator<MMessageProcessing<TMESSAGETYPE>> _enumeratorFlat;
		private readonly IEnumerator<MMessageProcessing<TMESSAGETYPE>> _enumeratorDeep;
		private readonly HandlerFunc _handler;
		private readonly bool _hasNohandler;

		public MMessageProcessing(string name)
		{
			_hasNohandler = true;
		}

		public MMessageProcessing(string name, MMessagingHandlerContext<TMESSAGETYPE> context, HandlerFunc handler)
		{
			Name = name;
			_handler = handler;
			_context = context;
			_enumeratorFlat = _handler(_context).GetEnumerator();
			_enumeratorDeep = TickInternal().GetEnumerator();
		}

		private IEnumerable<MMessageProcessing<TMESSAGETYPE>> TickInternal()
		{
			if (!IsFinished)
			{
				if (_hasNohandler)
				{
					IsFinished = true;
					yield return this;
				}
				else
				{
					while (_enumeratorFlat.MoveNext())
					{
						var subhandler = _enumeratorFlat.Current;
						foreach (var subsubHandler in subhandler.TickInternal())
							yield return subsubHandler;
					}

					IsFinished = true;
				}
			}
		}

		public bool Tick(TMESSAGETYPE currentMessage)
		{
			if (_hasNohandler)
			{
				if (IsFinished)
					return false;
				IsFinished = true;
				return true;
			}

			_context.CurrentMessage = currentMessage;
			if (!IsFinished)
			{
				if (_enumeratorDeep.MoveNext())
					return true;
			}

			return false;
		}
	}
}
